#version 460
#extension GL_GOOGLE_include_directive : enable
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require


#include "../../../../core/shader_binding_ID.h"
#include "../../../../core/shader_std.h"
#include "../../../../core/shader_built_in_functions.h"
#include "../../../../core/shader_mesh.h"


layout(triangles) in;
layout(line_strip, max_vertices=12) out;
//layout(triangle_strip, max_vertices=6) out;

//layout(input_primitive) in;


#include "../../../../core/shader_taster_geomFaceAttr.h"


layout(location = 0) in vec4 vColor[];
layout(location = 1) in vec3 vNormal[];
layout(location = 2) in vec3 vLightPos[][4];
layout(location = 6) in float vDepthScale[];
layout(location = 8) in uint vPrimitiveID[];
layout(location = 9) in uint vMeshOffset[];
layout(location = DEF_BINDING_LocationBindID_Vert) in vec3 vVert[];

//layout(location = DEF_BINDING_TasterBindID_PrimitiveID) in uint vPrimitiveID[];

layout(location = DEF_BINDING_LocationBindID_FaceAttr) in S_Geom_MeshDrawProp vFaceAttr[];
layout(location = DEF_BINDING_LocationBindID_RotMat) in mat4 vTranformMat[];
//layout(location = DEF_BINDING_LocationBindID_RotMat + 4) in mat4 vProjMat[];

in gl_PerVertex {
	vec4 gl_Position;
	float gl_PointSize;
}gl_in[];


layout(location = 0) out vec4 outColor;
layout(location = 1) out vec3 outNormal;
layout(location = 2) out vec3 outLightPos[4];
layout(location = 6) out float outDepthScale;
layout(location = 8) out uint outPrimitiveID;
layout(location = 9) flat out uint outMeshOffset;

out gl_PerVertex {
	vec4	gl_Position;
};


void main(void){

	vec3 edgeA = (vVert[1] - vVert[0]);
	vec3 edgeB = (vVert[2] - vVert[0]);
	vec3 edgeC = (vVert[1] - vVert[2]);
	vec3 Normal = normalize(cross(edgeA, edgeB));
	

	S_Geom_MeshDrawProp AttrOffset = vFaceAttr[0];
	vec3 Co = (vVert[0] + vVert[1] + vVert[2]) / 3;
	//gl_PrimitiveIDIn;


	uvec3 AdjacencyID = g_Face_AdjacencyID[AttrOffset.Offset_Face_AdjacencyID + gl_PrimitiveIDIn];
	uvec3 NormalAID = AdjacencyID + AttrOffset.Offset_Face_Normal;
	//uvec3 NormalAID = AdjacencyID;
	uvec3 CenterAID = AdjacencyID + AttrOffset.Offset_Face_Center;
	
	mat3 normalMat = mat3(vTranformMat[0]);
	//vec3 viewLine = vLightPos[0][0];
	vec3 viewLine = vLightPos[0][1] - (vTranformMat[0] * vec4(Co, 1)).xyz;
	//vec3 viewLine = vec3(1,0,0);
	vec3 MainNormal = normalize(g_Face_Normal[AttrOffset.Offset_Face_Normal + gl_PrimitiveIDIn]);
	float nv = dot(normalMat * Normal, viewLine);

	float depth = vDepthScale[0];

	if(nv < 0) return;

	//depth = 1;
	viewLine = vLightPos[0][1] - (vTranformMat[0] * vec4(g_Face_Center[CenterAID.x], 1)).xyz;
	//viewLine = vLightPos[0][1] - (vTranformMat[0] * vec4(edgeA*0.5 + vVert[0], 1)).xyz;
	//if(nv * dot(normalize(viewLine),  normalize(normalMat * g_Face_Normal[NormalAID.x])) <= 0.0){
	if(dot(viewLine, normalMat * g_Face_Normal[NormalAID.x]) <= 0.0){
		outColor = vColor[0];
		outDepthScale = depth;
		outPrimitiveID = gl_PrimitiveIDIn;
		outMeshOffset = vMeshOffset[0];
		//outColor = vec4(1,0,0,1);

		outNormal = Normal;
		gl_Position = gl_in[0].gl_Position;
		outLightPos[0] = vLightPos[0][0];
		outLightPos[1] = vLightPos[0][1];
		outLightPos[2] = vLightPos[0][2];
		outLightPos[3] = vLightPos[0][3];
		EmitVertex();


		outColor = vColor[1];
		outDepthScale = depth;
		outPrimitiveID = gl_PrimitiveIDIn;
		outMeshOffset = vMeshOffset[0];
		//outColor = vec4(1,0,0,1);

		outNormal = Normal;
		gl_Position = gl_in[1].gl_Position;
		outLightPos[0] = vLightPos[1][0];
		outLightPos[1] = vLightPos[1][1];
		outLightPos[2] = vLightPos[1][2];
		outLightPos[3] = vLightPos[1][3];
		
		EmitVertex();
		EndPrimitive();
	}
	
	viewLine = vLightPos[0][1] - (vTranformMat[1] * vec4(g_Face_Center[CenterAID.y], 1)).xyz;
	//viewLine = vLightPos[0][1] - (vTranformMat[1] * vec4(edgeC*0.5 + vVert[2], 1)).xyz;
	//if(nv * dot(normalize(viewLine), normalize(normalMat * g_Face_Normal[NormalAID.y])) <= 0.0){
	if(dot(viewLine, normalMat * g_Face_Normal[NormalAID.y]) <= 0.0){
		outColor = vColor[1];
		outDepthScale = depth;
		outPrimitiveID = gl_PrimitiveIDIn;
		outMeshOffset = vMeshOffset[0];
		//outColor = vec4(0,1,0,1);

		outNormal = Normal;
		gl_Position = gl_in[1].gl_Position;
		outLightPos[0] = vLightPos[1][0];
		outLightPos[1] = vLightPos[1][1];
		outLightPos[2] = vLightPos[1][2];
		outLightPos[3] = vLightPos[1][3];
		
		EmitVertex();

		outColor = vColor[2];
		outDepthScale = depth;
		outPrimitiveID = gl_PrimitiveIDIn;
		outMeshOffset = vMeshOffset[0];
		//outColor = vec4(0,1,0,1);

		outNormal = Normal;
		gl_Position = gl_in[2].gl_Position;
		outLightPos[0] = vLightPos[2][0];
		outLightPos[1] = vLightPos[2][1];
		outLightPos[2] = vLightPos[2][2];
		outLightPos[3] = vLightPos[2][3];
		
		EmitVertex();

		EndPrimitive();
	}

	viewLine = vLightPos[0][1] - (vTranformMat[2] * vec4(g_Face_Center[CenterAID.z], 1)).xyz;
	//viewLine = vLightPos[0][1] - (vTranformMat[1] * vec4(edgeB*0.5 + vVert[0], 1)).xyz;
	//if(nv * dot(normalize(viewLine), normalize(normalMat * g_Face_Normal[NormalAID.z])) <= 0.0){
	if(dot(viewLine, normalMat * g_Face_Normal[NormalAID.z]) <= 0.0){
		outColor = vColor[2];
		outDepthScale = depth;
		outPrimitiveID = gl_PrimitiveIDIn;
		outMeshOffset = vMeshOffset[0];
		//outColor = vec4(0,0,1,1);

		outNormal = Normal;
		gl_Position = gl_in[2].gl_Position;
		outLightPos[0] = vLightPos[2][0];
		outLightPos[1] = vLightPos[2][1];
		outLightPos[2] = vLightPos[2][2];
		outLightPos[3] = vLightPos[2][3];
		
		EmitVertex();

		outColor = vColor[0];
		outDepthScale = depth;
		outPrimitiveID = gl_PrimitiveIDIn;
		outMeshOffset = vMeshOffset[0];
		//outColor = vec4(0,0,1,1);

		outNormal = Normal;
		gl_Position = gl_in[0].gl_Position;
		outLightPos[0] = vLightPos[0][0];
		outLightPos[1] = vLightPos[0][1];
		outLightPos[2] = vLightPos[0][2];
		outLightPos[3] = vLightPos[0][3];
		
		EmitVertex();
		EndPrimitive();
	}

	return;
}



/*

	outNormal = Normal;
	outColor = vec4(1,1,1,1);
	gl_Position = (vTranformMat[0] * vec4(Co, 1));
	EmitVertex();

	outNormal = Normal;
	outColor = vec4(1,0,1,1);
	//gl_Position = (vRotMat[0] * vec4(Co + normalize(g_Face_Normal[AdjacencyID.x]), 1));
	//viewLine = vLightPos[1][1] - (vRotMat[0] * vec4(g_Face_Center[CenterAID.x], 1)).xyz;
	//gl_Position = vRotMat[0] * vec4(Co + normalize(viewLine), 1);
	gl_Position = vTranformMat[0] * vec4(Co + Normal, 1);
	EmitVertex();
	EndPrimitive();


	outNormal = Normal;
	outColor = vec4(1,1,1,1);
	gl_Position = (vTranformMat[0] * vec4(Co, 1));
	EmitVertex();

	outNormal = Normal;
	outColor = vec4(1,1,0,1);
	viewLine = vLightPos[1][1] - (vec4(g_Face_Center[CenterAID.x], 1)).xyz;
	//viewLine = vLightPos[1][1];
	gl_Position = vTranformMat[0] * vec4(viewLine, 1);
	//gl_Position = (vRotMat[0] * vec4(Co + (g_Face_Normal[AttrOffset.Offset_Face_Normal + gl_PrimitiveIDIn]) + 1, 1));
	//gl_Position = vRotMat[0] * vec4(Co + viewLine, 1);
	EmitVertex();
	EndPrimitive();

	return;
	
		//outColor = vec4(1,0,0,1);
		outColor.xyz = g_Face_Normal[AdjacencyID.x];
		//outColor.xyz = vec3(AdjacencyID.x, 0,0);
		outNormal = Normal;
		gl_Position = gl_in[0].gl_Position;
		outLightPos[0] = vLightPos[0][0];
		outLightPos[1] = vLightPos[0][1];
		outLightPos[2] = vLightPos[0][2];
		outLightPos[3] = vLightPos[0][3];
		EmitVertex();
//	outColor = vec4(1,0,0,1);
		outColor.xyz = g_Face_Normal[AdjacencyID.x];
		//outColor.xyz = vec3(AdjacencyID.x, 0,0);
		outNormal = Normal;
		gl_Position = gl_in[1].gl_Position;
		outLightPos[0] = vLightPos[1][0];
		outLightPos[1] = vLightPos[1][1];
		outLightPos[2] = vLightPos[1][2];
		outLightPos[3] = vLightPos[1][3];
		EmitVertex();
		EndPrimitive();
////	outColor = vec4(0,1,0,1);
		outColor.xyz = g_Face_Normal[AdjacencyID.y];
		//outColor.xyz = vec3(0, AdjacencyID.y, 0);
		outNormal = Normal;
		gl_Position = gl_in[1].gl_Position;
		outLightPos[0] = vLightPos[1][0];
		outLightPos[1] = vLightPos[1][1];
		outLightPos[2] = vLightPos[1][2];
		outLightPos[3] = vLightPos[1][3];
		EmitVertex();
//	outColor = vec4(0,1,0,1);
		outColor.xyz = g_Face_Normal[AdjacencyID.y];
		//outColor.xyz = vec3(0, AdjacencyID.y, 0);
		outNormal = Normal;
		gl_Position = gl_in[2].gl_Position;
		outLightPos[0] = vLightPos[2][0];
		outLightPos[1] = vLightPos[2][1];
		outLightPos[2] = vLightPos[2][2];
		outLightPos[3] = vLightPos[2][3];
		EmitVertex();
		EndPrimitive();
////	outColor = vec4(0,0,1,1);
		outColor.xyz = g_Face_Normal[AdjacencyID.z];
		//outColor.xyz = vec3(0, 0, AdjacencyID.z);
		outNormal = Normal;
		gl_Position = gl_in[2].gl_Position;
		outLightPos[0] = vLightPos[2][0];
		outLightPos[1] = vLightPos[2][1];
		outLightPos[2] = vLightPos[2][2];
		outLightPos[3] = vLightPos[2][3];
		EmitVertex();
//	outColor = vec4(0,0,1,1);
		outColor.xyz = g_Face_Normal[AdjacencyID.z];
		//outColor.xyz = vec3(0, 0, AdjacencyID.z);
		outNormal = Normal;
		gl_Position = gl_in[0].gl_Position;
		outLightPos[0] = vLightPos[0][0];
		outLightPos[1] = vLightPos[0][1];
		outLightPos[2] = vLightPos[0][2];
		outLightPos[3] = vLightPos[0][3];
		EmitVertex();
		EndPrimitive();
	
	return;

*/